package tr.mesir.view;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.queryParser.ParseException;
import org.richfaces.component.html.HtmlDataTable;
import org.richfaces.component.html.HtmlSubTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import tr.mesir.domain.AddressBook;
import tr.mesir.domain.Contact;
import tr.mesir.domain.wrappers.ContactVersionWrapper;
import tr.mesir.service.AddressBookService;

/**
 * This is the backing-bean which is used by the facelet pages.
 * 
 * @Controller annotation represents the class as a web controller backing-bean. The logical component name
 * is also provided to be used while turning the instance into a spring-bean. 
 * JSF2.0 comes with the @ManagedBean annotation for the backing-beans, but it's a little late progress as
 * compared to the spring annotations.Why bother while using those ;)
 * 
 * @Scope annotation represents a target scope to hold the bean references in. With this controller,
 * it's scoped in the conversation context that we defined in the spring configuration file. 
 * 
 * @author mertcaliskan
 */
@Controller("addressBookController")
@Scope("conversation.access")
public class AddressBookController extends PageCodeBase {

	// using slf4j for logging stuff...
	private static Logger logger = LoggerFactory.getLogger(AddressBookController.class);
	
	// Table bindings...
	private HtmlDataTable tblSearchResult;
	private HtmlSubTable tblContacts;
	
	/* @AutoWired is used to autowiring the addressBookService bean by type into the specified property. 
	 * It can also be used to mark a constructor (one constructor at max), field, setter method.
	 */
	@Autowired
	private AddressBookService addressBookService;
	
	private List<AddressBook> addressBookVersions;
	private List<ContactVersionWrapper> contactVersions;

	// pivot properties to handle the adding/updating of addressBook and contact
	private AddressBook addressBook = new AddressBook();
	private Contact contact = new Contact();

	// properties used by Hibernate Search
	private String searchText;
	private List<AddressBook> addressBookSearchResult;
	
	public List<AddressBook> getAddressBooks() {
		return addressBookService.findAll();
	}

	public AddressBook getAddressBook() {
		return addressBook;
	}

	public void setAddressBook(AddressBook addressBook) {
		this.addressBook = addressBook;
	}
	
	public Contact getContact() {
		return contact;
	}

	public void setContact(Contact contact) {
		this.contact = contact;
	}
	
	public String getSearchText() {
		return searchText;
	}

	public void setSearchText(String searchText) {
		this.searchText = searchText;
	}
	
	public String doSearch() {
		try {
			logger.debug("Searching with text {}", getSearchText());
			setAddressBookSearchResult(addressBookService.findByWord(getSearchText()));
		} 
		catch (ParseException e) {
			addFacesMessageError("Error occured while doing search with text: " + getSearchText());
			logger.error("Error occured while doing search", e);
		}
		
		return "";
	}
	
	public String addContactToAddressBook() {
		setAddressBook((AddressBook) getTblSearchResult().getRowData());
		
		return "contact";
	}
	
	public String editAddressBook() {
		setAddressBook((AddressBook) getTblSearchResult().getRowData());
		
		return "addressBook";
	}
	
	public String editContact() {
		setAddressBook((AddressBook) getTblSearchResult().getRowData());
		setContact((Contact) getTblContacts().getRowData());
		 
		return "contact";
	}
	
	public String addContact() {
		if (!getAddressBook().getContacts().contains(getContact()))
			getAddressBook().getContacts().add(getContact());
		addressBookService.update(getAddressBook());
		logger.debug("Contact {} to address book {}", getContact().getName(), getAddressBook().getTitle());
		
		setAddressBook(new AddressBook());
		setContact(new Contact());
		
		return "addressBooks";
	}	
	
	public String saveAddressBook() {
		addressBookService.save(getAddressBook());
		setAddressBook(new AddressBook());
		
		return "addressBooks";
	}
	
	public List<AddressBook> getAddressBookSearchResult() {
		return addressBookSearchResult;
	}

	public void setAddressBookSearchResult(List<AddressBook> addressBookSearchResult) {
		this.addressBookSearchResult = addressBookSearchResult;
	}

	public HtmlDataTable getTblSearchResult() {
		return tblSearchResult;
	}

	public void setTblSearchResult(HtmlDataTable tblSearchResult) {
		this.tblSearchResult = tblSearchResult;
	}

	public HtmlSubTable getTblContacts() {
		return tblContacts;
	}

	public void setTblContacts(HtmlSubTable tblContacts) {
		this.tblContacts = tblContacts;
	}

	public List<AddressBook> getAddressBookVersions() {
		String addressBookID = getRequestVal("addressBookID");
		if (StringUtils.isNotEmpty(addressBookID)) {
			setAddressBookVersions(addressBookService.getAddressBookVersions(new Long(addressBookID)));
		}
		
		return addressBookVersions;
	}

	public void setAddressBookVersions(List<AddressBook> addressBookVersions) {
		this.addressBookVersions = addressBookVersions;
	}

	public List<ContactVersionWrapper> getContactVersions() {
		String contactID = getRequestVal("contactID");
		if (StringUtils.isNotEmpty(contactID)) {
			setContactVersions(addressBookService.getContactVersions(new Long(contactID)));
		}
		
		return contactVersions;
	}

	public void setContactVersions(List<ContactVersionWrapper> contactVersions) {
		this.contactVersions = contactVersions;
	}
}